package com.olap.starter.util.sql;

import com.olap.starter.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

//解析sql中的表名
public class SqlParseTableName {

    public static void main(String[] args) {
        String sql = "select a,b,c from table1 t1 left join table2 t2 on t1.id=t2.parentId left join table3 on t1.id = t3.parentId";
        List<String> tableName = execute(sql);
        System.out.println(tableName);
    }
    public static List<String> execute(String sql){
        return getTableName(sql);
    }

    public static List<String> getTableName(String sql) {

        List<String> tableNames = new ArrayList<>();
        tableNames = doGetTableNames(sql, "from", tableNames);
        tableNames = doGetTableNames(sql, "join", tableNames);

        return tableNames;
    }

    private static List<String> doGetTableNames(String sql, String keyword, List<String> tableNames)  {
        if(StringUtils.isEmpty(sql))
        {
            throw new RuntimeException("sql语句为空,获取表名失败");
        }

        String partSql = sql.toLowerCase();
        int index = 0;
        while(index >= 0)
        {
            index = partSql.indexOf(keyword);

            if(index-1 >= 0 && index + keyword.length() < partSql.length())
            {
                char beforeChar = partSql.charAt(index-1);

                partSql = partSql.substring(index + keyword.length());

                if(beforeChar != '\n' && beforeChar != '\t' && beforeChar != '\r' && beforeChar != ' ')
                {
                    continue;
                }

                boolean isBreak = false;
                int startIndex = 0;
                while(!isBreak)
                {
                    if(startIndex < partSql.length())
                    {
                        char ch = partSql.charAt(startIndex);

                        if(Character.isLowerCase(ch) || Character.isUpperCase(ch) ||
                                Character.isDigit(ch) || ch == '_' || ch == '$')
                        {
                            if(startIndex == 0)
                            {
                                startIndex = -1;
                            }
                            isBreak = true;
                        }
                        else if(ch == '(')
                        {
                            startIndex = -1;
                            isBreak = true;
                        }
                        else
                        {
                            startIndex ++;
                        }

                    }
                    else
                    {
                        startIndex = -1;
                        isBreak = true;
                    }

                }

                if( startIndex == -1)
                {
                    continue;
                }

                int endIndex = startIndex+1;

                if(endIndex > 0)
                {
                    isBreak = false;

                    while(!isBreak)
                    {
                        if(endIndex < partSql.length())
                        {
                            char ch = partSql.charAt(endIndex);

                            if(!Character.isLowerCase(ch) && !Character.isUpperCase(ch) &&
                                    !Character.isDigit(ch) && ch != '_' && ch != '$')
                            {
                                isBreak = true;
                            }
                            else
                            {
                                endIndex ++;
                            }
                        }
                        else
                        {
                            endIndex = -1;
                            isBreak = true;
                        }

                    }

                    if(endIndex > startIndex)
                    {
                        String tableName = partSql.substring(startIndex, endIndex);

                        if(!tableNames.contains(tableName))
                        {
                            tableNames.add(tableName);
                        }

                        if(endIndex < partSql.length())
                        {
                            partSql = partSql.substring(endIndex + 1);
                        }
                    }
                }
            }
        }

        return tableNames;
    }
}
